package com.qf.rbac2202.annotation;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.rbac2202.sys.entity.SysRoleDept;
import com.qf.rbac2202.sys.entity.SysUser;
import com.qf.rbac2202.sys.entity.SysUserRole;
import com.qf.rbac2202.sys.service.ISysRoleDeptService;
import com.qf.rbac2202.sys.service.ISysUserRoleService;
import com.qf.rbac2202.utils.Constants;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;




@Component
@Aspect//代表该类是一个切面
public class DataFilterAspect {
	@Autowired
	ISysUserRoleService iSysUserRoleService;

	@Autowired
	ISysRoleDeptService iSysRoleDeptService;

	//改切点切的是加了DataFilter注解的方法
	@Pointcut("@annotation(com.qf.rbac2202.annotation.DataFilter)")
	public void pointcut() {}


	//配置切面参数是具体的切点方法名
	//JoinPoint 获取方法的参数
	@Before("pointcut()")
	public void  before( JoinPoint joinPoint ){
		//把过滤数据权限的sql片段添加到当前方法的第一个参数
		//约定必须map类型

		//通过joinpoint 获取签名对象
		//通过反射api 获取DataFilter 配置拼接字段
		MethodSignature signature=(MethodSignature) joinPoint.getSignature( );
		Method method=signature.getMethod( );

		DataFilter annotation=method.getAnnotation( DataFilter.class );
		String s=annotation.dataFieldName( );


		//拼接sql xxx in (1,2,3)
		//超级管理员的特殊情况处理
		String s1=getdeptString( );
		if (s1==null) {
			return;
         }

		//如果查完后没有权限就改变值
		if(s1.equals( "()" )){
			s1="("+-1+")";
		}
		String sql="("+s+"in"+s1+")";

		//通过反射,获取方法的所有参数
		Object[] args=joinPoint.getArgs( );
		Object arg=args[0];
		if(arg!=null&&arg instanceof Map) {
			((Map) arg).put( Constants.DATA_FILETER,sql );
		}
	}

	//获取当前用户的数据权限字符串
	//如果是管理员 直接获取全部
	private String getdeptString( ) {
		//根据当前用户查询所有的部门ids
		Subject subject=SecurityUtils.getSubject( );
		SysUser principal=(SysUser) subject.getPrincipal( );

		//如果是超级管理员直接返回空
		if(principal.getUserId().equals( Constants.SUPER_ADMIN )){
			return null;
		}

		QueryWrapper< SysUserRole > user_id=new QueryWrapper< SysUserRole >( )
				.select( "role_id" )
				.eq( "user_id",principal.getUserId( ) );
		List< Object > roleIdList=iSysUserRoleService.listObjs( user_id );

		QueryWrapper< SysRoleDept > deptIdList=new QueryWrapper< SysRoleDept >( )
				.select( "dept_id" )
				.in( "role_id",roleIdList );
		List< Object > deptIdListS=iSysRoleDeptService.listObjs( deptIdList );

		//deptIdListS转换为（1,2,3）
		String deptString=deptIdListS.stream( )
				.map( Object::toString )
				.collect( Collectors.joining( ",","(",")" ) );

		return deptString;
	}
}
